Browse Source

Gmt module: Error reporting in all Convert functions.

gmtdatadir
Michael Uleysky 8 years ago
parent
commit
a3a6fa88f9
  1. 123
      modules/gmt/modgmt_structs.h

123
modules/gmt/modgmt_structs.h

@ -32,7 +32,7 @@ class GetDouble<Source, Policy, Policies...>: public GetDouble<Source, Policies.
GetDouble(GetDouble&) = delete; GetDouble(GetDouble&) = delete;
template<class... Args> template<class... Args>
GetDouble(Args... args):GetDouble<Source,Policies...>(args...) {}; GetDouble(Args... args):GetDouble<Source,Policies...>(args...) {};
double operator()(bool* suc) const {return p(GetDouble<Source,Policies...>::operator()(suc),suc);} double operator()(bool* suc, std::string& err) const {return p(GetDouble<Source,Policies...>::operator()(suc,err),suc,err);}
}; };
// Bottom of recursion // Bottom of recursion
@ -45,37 +45,57 @@ class GetDouble<Source>: public Source
GetDouble() = delete; GetDouble() = delete;
template<class... Args> template<class... Args>
GetDouble(Args... args):Source(args...) {}; GetDouble(Args... args):Source(args...) {};
double operator()(bool* suc) const {return Source::operator()(suc);} double operator()(bool* suc, std::string& err) const {return Source::operator()(suc, err);}
}; };
// We use rational representation of floating point number, because double type values not allowed as template parameter // We use rational representation of floating point number, because double type values not allowed as template parameter
// Policy to check if value is greater or equal num/denum // Policy to check if value is greater or equal num/denum
template<int32_t num, uint32_t denum=1> template<int32_t num, uint32_t denum=1, bool equal=true>
class PMin class PMin
{ {
static bool Compare(double d1, double d2) {return equal?(d1<=d2):(d1<d2);}
public: public:
double operator()(double v, bool* suc) const {if(v<static_cast<double>(num)/denum) *suc=false; return v;} double operator()(double v, bool* suc, std::string& err) const
{
if(Compare(v,static_cast<double>(num)/denum))
{
*suc=false;
if(err.empty()) err="Value "+ToString(v)+" must be greater "+(equal?"or equal ":"")+"then "+ToString(num)+((denum==1)?"":("/"+ToString(denum)));
}
return v;
}
}; };
// Policy to check if value is lesser or equal num/denum // Policy to check if value is lesser or equal num/denum
template<int32_t num, uint32_t denum=1> template<int32_t num, uint32_t denum=1, bool equal=true>
class PMax class PMax
{ {
static bool Compare(double d1, double d2) {return equal?(d1>=d2):(d1>d2);}
public: public:
double operator()(double v, bool* suc) const {if(v>static_cast<double>(num)/denum) *suc=false; return v;} double operator()(double v, bool* suc, std::string& err) const
{
if(Compare(v,static_cast<double>(num)/denum))
{
*suc=false;
if(err.empty()) err="Value "+ToString(v)+" must be lesser "+(equal?"or equal ":"")+"then "+ToString(num)+((denum==1)?"":("/"+ToString(denum)));
}
return v;
}
}; };
// Get double value from string or number // Get double value from string or number
class SourceValue class SourceValue
{ {
double d; double d;
bool ok; std::string err;
public: public:
SourceValue(const std::string& s) {ok=str2double(s,&d);} SourceValue(const std::string& s) {if(!str2double(s,&d)) err="Can't convert string \""+s+"\" to double value";}
SourceValue(double s):d(s),ok(true) {} SourceValue(double s):d(s) {}
double operator()(bool* suc) const double operator()(bool* suc, std::string& ierr) const
{ {
if(!ok) *suc=false; if(!err.empty()) {*suc=false; ierr=err;}
return d; return d;
} }
}; };
@ -83,7 +103,7 @@ class SourceValue
// Helper types for colors // Helper types for colors
typedef GetDouble<SourceValue,PMin<0>,PMax<255> > Value2RGB; typedef GetDouble<SourceValue,PMin<0>,PMax<255> > Value2RGB;
typedef GetDouble<SourceValue,PMin<0>,PMax<360> > Value2Hue; typedef GetDouble<SourceValue,PMin<0>,PMax<360> > Value2Hue;
typedef GetDouble<SourceValue,PMin<0>,PMax<1> > Value2SV; typedef GetDouble<SourceValue,PMin<0>,PMax< 1 > > Value2SV;
typedef GetDouble<SourceValue,PMin<0>,PMax<100> > Value2CMYK; typedef GetDouble<SourceValue,PMin<0>,PMax<100> > Value2CMYK;
typedef GetDouble<SourceValue,PMin<0>,PMax<100> > Value2Transp; typedef GetDouble<SourceValue,PMin<0>,PMax<100> > Value2Transp;
// Helper type for pens and dashes // Helper type for pens and dashes
@ -546,17 +566,17 @@ struct gmt_color: public gmt_struct
} }
// Interpret one numeric argument as gray value // Interpret one numeric argument as gray value
bool Convert(double gr) bool Convert(double gr, std::string& err)
{ {
Value2RGB g(gr); Value2RGB g(gr);
bool suc=true; bool suc=true;
model=GRAY; model=GRAY;
transparency=0.0; transparency=0.0;
gray=g(&suc); gray=g(&suc,err);
return suc; return suc;
} }
bool Convert(const std::string& istr) bool Convert(const std::string& istr, std::string& err)
{ {
std::string cstr=istr; std::string cstr=istr;
tolower(cstr); tolower(cstr);
@ -573,7 +593,7 @@ struct gmt_color: public gmt_struct
cstr=*ci; cstr=*ci;
ci++; ci++;
Value2Transp t(*ci); Value2Transp t(*ci);
transparency=t(&suc); transparency=t(&suc,err);
if(!suc) return false; // Parse error if(!suc) return false; // Parse error
} }
} }
@ -581,9 +601,9 @@ struct gmt_color: public gmt_struct
WordList wl_slash=Split(cstr,"/"),wl_hyphen=Split(cstr,"-"); WordList wl_slash=Split(cstr,"/"),wl_hyphen=Split(cstr,"-");
WordList::size_type slash_size=wl_slash.size(),hyphen_size=wl_hyphen.size(); WordList::size_type slash_size=wl_slash.size(),hyphen_size=wl_hyphen.size();
// Checks // Checks
if(slash_size>1 && hyphen_size>1) return false; // Delimiter can be "/" or "-", not both if(slash_size>1 && hyphen_size>1) {err="Delimeter of color components must be \"/\" or \"-\", not both"; return false;}
if(2==slash_size || slash_size>4) return false; // Size can be 1 or 3 for rgb or 4 for cmyk if(2==slash_size || slash_size>4) {err="Number of color components must be 1 for GRAY, 3 for RGB or 4 for CMYK"; return false;}
if(2==hyphen_size || hyphen_size>3) return false; // Size can be 1 or 3 for hsv if(2==hyphen_size || hyphen_size>3) {err="There is 3 color components in HSV model"; return false;}
// Gray or name // Gray or name
// TODO: Hex representation // TODO: Hex representation
if(1==slash_size && 1==hyphen_size) if(1==slash_size && 1==hyphen_size)
@ -592,7 +612,8 @@ struct gmt_color: public gmt_struct
Value2RGB g(cstr); Value2RGB g(cstr);
bool suc=true; bool suc=true;
model=GRAY; model=GRAY;
gray=g(&suc); gray=g(&suc,err);
err="Can't understand string "+cstr+", this is nor color name, nor gray value (0-255)";
return suc; return suc;
} }
// RGB // RGB
@ -603,9 +624,9 @@ struct gmt_color: public gmt_struct
Value2RGB blue(wl_slash.front()); Value2RGB blue(wl_slash.front());
bool suc=true; bool suc=true;
model=RGB; model=RGB;
r=red(&suc); r=red(&suc,err); if(!suc) return suc;
g=green(&suc); g=green(&suc,err);if(!suc) return suc;
b=blue(&suc); b=blue(&suc,err);
return suc; return suc;
} }
// HSV // HSV
@ -616,9 +637,9 @@ struct gmt_color: public gmt_struct
Value2SV v(wl_hyphen.front()); Value2SV v(wl_hyphen.front());
bool suc=true; bool suc=true;
model=HSV; model=HSV;
hue=h(&suc); hue=h(&suc,err); if(!suc) return suc;
saturation=s(&suc); saturation=s(&suc,err);if(!suc) return suc;
value=v(&suc); value=v(&suc,err);
return suc; return suc;
} }
// CMYK // CMYK
@ -630,10 +651,10 @@ struct gmt_color: public gmt_struct
Value2CMYK k(wl_slash.front()); Value2CMYK k(wl_slash.front());
bool suc=true; bool suc=true;
model=CMYK; model=CMYK;
cyan=c(&suc); cyan=c(&suc,err); if(!suc) return suc;
magenta=m(&suc); magenta=m(&suc,err);if(!suc) return suc;
yellow=y(&suc); yellow=y(&suc,err); if(!suc) return suc;
black=k(&suc); black=k(&suc,err);
return suc; return suc;
} }
} }
@ -678,7 +699,7 @@ struct gmt_dash: public gmt_struct
operator bool() const {return !dash.empty();} operator bool() const {return !dash.empty();}
void Clear() {dash.clear(); shift=0.0; wisrel=false;} void Clear() {dash.clear(); shift=0.0; wisrel=false;}
bool Convert(const std::string& in, double w=0.0) bool Convert(const std::string& in, std::string& err, double w=0.0)
{ {
Clear(); Clear();
shift=0; shift=0;
@ -704,7 +725,7 @@ struct gmt_dash: public gmt_struct
{ {
Value2Width s(wl.back()); Value2Width s(wl.back());
bool suc=true; bool suc=true;
shift=s(&suc); shift=s(&suc,err);
if(!suc) return false; // Parse error if(!suc) return false; // Parse error
dstr=wl.front(); dstr=wl.front();
} }
@ -714,7 +735,7 @@ struct gmt_dash: public gmt_struct
{ {
Value2Width d(i); Value2Width d(i);
bool suc=true; bool suc=true;
dash.push_back(d(&suc)); dash.push_back(d(&suc,err));
if(!suc) return false; // Parse error if(!suc) return false; // Parse error
} }
return true; return true;
@ -732,18 +753,18 @@ struct gmt_pen: public gmt_struct
std::string Value() const {return ToString(width/10.0)+"c,"+color.Value()+(dash?(","+dash.Value()):"");} std::string Value() const {return ToString(width/10.0)+"c,"+color.Value()+(dash?(","+dash.Value()):"");}
// Interpret one numeric argument as width value // Interpret one numeric argument as width value
bool Convert(double in) bool Convert(double in, std::string& err)
{ {
Value2Width w(in); Value2Width w(in);
bool suc=true; bool suc=true;
color.Convert(0); // Black color.Convert(0,err); // Black
dash.Clear(); dash.Clear();
width=w(&suc); width=w(&suc,err);
return suc; return suc;
} }
// Convert from string // Convert from string
bool Convert(const std::string& istr) bool Convert(const std::string& istr, std::string& err)
{ {
std::string str=istr; std::string str=istr;
WordList::const_iterator ci; WordList::const_iterator ci;
@ -752,7 +773,7 @@ struct gmt_pen: public gmt_struct
// Defaults // Defaults
width=default_width; width=default_width;
color.Convert(0); // Black color.Convert(0,err); // Black
dash.Clear(); dash.Clear();
if(wl.size()>3) return false; // String is [width][,color][,dash] if(wl.size()>3) return false; // String is [width][,color][,dash]
@ -761,18 +782,18 @@ struct gmt_pen: public gmt_struct
{ {
Value2Width w(*ci); Value2Width w(*ci);
bool suc=true; bool suc=true;
width=w(&suc); width=w(&suc,err);
if(!suc) return false; // Parse error if(!suc) return false; // Parse error
} }
if(wl.end()!=ci) ci++; if(wl.end()!=ci) ci++;
if(wl.end()!=ci && 0!=ci->size()) if(wl.end()!=ci && 0!=ci->size())
{ {
if(!color.Convert(*ci)) return false; // Parse error if(!color.Convert(*ci,err)) return false; // Parse error
} }
if(wl.end()!=ci) ci++; if(wl.end()!=ci) ci++;
if(wl.end()!=ci && 0!=ci->size()) if(wl.end()!=ci && 0!=ci->size())
{ {
if(!dash.Convert(*ci,width)) return false; // Parse error if(!dash.Convert(*ci,err,width)) return false; // Parse error
} }
return true; return true;
} }
@ -792,18 +813,18 @@ struct gmt_font: public gmt_struct
std::string Value() const {return ToString(size)+"p,"+family+","+color.Value();} std::string Value() const {return ToString(size)+"p,"+family+","+color.Value();}
// Interpret one numeric argument as size of default black font // Interpret one numeric argument as size of default black font
bool Convert(double in) bool Convert(double in, std::string& err)
{ {
Value2Width s(in); Value2Width s(in);
bool suc=true; bool suc=true;
color.Convert(0); // Black color.Convert(0,err); // Black
size=s(&suc); size=s(&suc,err);
family=default_family; family=default_family;
return suc; return suc;
} }
// Convert from string // Convert from string
bool Convert(const std::string& str) bool Convert(const std::string& str, std::string& err)
{ {
WordList::const_iterator ci; WordList::const_iterator ci;
WordList wl=Split(str,",",true); WordList wl=Split(str,",",true);
@ -811,34 +832,34 @@ struct gmt_font: public gmt_struct
// Defaults // Defaults
size=default_size; size=default_size;
family=default_family; family=default_family;
color.Convert(0); // Black color.Convert(0,err); // Black
if(wl.size()>3) return false; // String is [size][,family][,color] or [family][,color] if(wl.size()>3) {err="String "+str+" is not font string"; return false;} // String is [size][,family][,color] or [family][,color]
ci=wl.begin(); ci=wl.begin();
if(wl.end()!=ci && 0!=ci->size()) if(wl.end()!=ci && 0!=ci->size())
{ {
Value2Width s(*ci); Value2Width s(*ci);
bool suc=true; bool suc=true;
size=s(&suc); {std::string fake; size=s(&suc,fake);}
if(!suc) // Parse error. check if argument is font name if(!suc) // Parse error. check if argument is font name
{ {
if(0==families.count(*ci)) return false; // No, argument is not allowed font name if(0==families.count(*ci)) return false; // No, argument is not allowed font name
family=*ci; family=*ci;
if(wl.size()>2) return false; // If first word is font name, then words count is 1 or 2. if(wl.size()>2) {err="String "+str+" is not font string"; return false;} // If first word is font name, then words count is 1 or 2.
goto read_color; goto read_color;
} }
} }
if(wl.end()!=ci) ci++; if(wl.end()!=ci) ci++;
if(wl.end()!=ci && 0!=ci->size()) if(wl.end()!=ci && 0!=ci->size())
{ {
if(0==families.count(*ci)) return false; // Argument is not allowed font name if(0==families.count(*ci)) {err="Unknown font family: "+(*ci); return false;} // Argument is not allowed font name
family=*ci; family=*ci;
} }
read_color: read_color:
if(wl.end()!=ci) ci++; if(wl.end()!=ci) ci++;
if(wl.end()!=ci && 0!=ci->size()) if(wl.end()!=ci && 0!=ci->size())
{ {
if(!color.Convert(*ci)) return false; // Parse error if(!color.Convert(*ci,err)) return false; // Parse error
} }
return true; return true;
} }

Loading…
Cancel
Save