MQTTSuite
Loading...
Searching...
No Matches
anonymous_namespace{string-format-check.cpp} Namespace Reference

Functions

template<typename T>
void range_check (const T value, const T min, const T max)
void rfc3339_date_check (const std::string &value)
void rfc3339_time_check (const std::string &value)
void rfc3339_date_time_check (const std::string &value)
bool is_ascii (std::string const &value)
void rfc3986_uri_check (const std::string &value)

Variables

const std::string decOctet {R"((?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]))"}
const std::string ipv4Address {"(?:" + decOctet + R"(\.){3})" + decOctet}
const std::string h16 {R"([0-9A-Fa-f]{1,4})"}
const std::string h16Left {"(?:" + h16 + ":)"}
const std::string ipv6Address
const std::string ipvFuture {R"([Vv][0-9A-Fa-f]+\.[A-Za-z0-9\-._~!$&'()*+,;=:]+)"}
const std::string regName {R"((?:[A-Za-z0-9\-._~!$&'()*+,;=]|%[0-9A-Fa-f]{2})*)"}
const std::string host
const std::string uuid {R"([0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12})"}
const std::string hostname {R"(^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$)"}

Detailed Description

Function Documentation

◆ is_ascii()

bool anonymous_namespace{string-format-check.cpp}::is_ascii ( std::string const & value)

Definition at line 195 of file string-format-check.cpp.

196{
197 for (auto ch : value) {
198 if (ch & 0x80) {
199 return false;
200 }
201 }
202 return true;
203}

Referenced by nlohmann::json_schema::default_string_format_check().

Here is the caller graph for this function:

◆ range_check()

template<typename T>
void anonymous_namespace{string-format-check.cpp}::range_check ( const T value,
const T min,
const T max )

Definition at line 31 of file string-format-check.cpp.

32{
33 if (!((value >= min) && (value <= max))) {
34 std::stringstream out;
35 out << "Value " << value << " should be in interval [" << min << "," << max << "] but is not!";
36 throw std::invalid_argument(out.str());
37 }
38}

Referenced by rfc3339_date_check(), and rfc3339_time_check().

Here is the caller graph for this function:

◆ rfc3339_date_check()

void anonymous_namespace{string-format-check.cpp}::rfc3339_date_check ( const std::string & value)
See also
date_time_check

Definition at line 41 of file string-format-check.cpp.

42{
43 const static REGEX_NAMESPACE::regex dateRegex{R"(^([0-9]{4})\-([0-9]{2})\-([0-9]{2})$)"};
44
45 REGEX_NAMESPACE::smatch matches;
46 if (!REGEX_NAMESPACE::regex_match(value, matches, dateRegex)) {
47 throw std::invalid_argument(value + " is not a date string according to RFC 3339.");
48 }
49
50 const auto year = std::stoi(matches[1].str());
51 const auto month = std::stoi(matches[2].str());
52 const auto mday = std::stoi(matches[3].str());
53
54 const auto isLeapYear = (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
55
56 range_check(month, 1, 12);
57 if (month == 2) {
58 range_check(mday, 1, isLeapYear ? 29 : 28);
59 } else if (month <= 7) {
60 range_check(mday, 1, month % 2 == 0 ? 30 : 31);
61 } else {
62 range_check(mday, 1, month % 2 == 0 ? 31 : 30);
63 }
64}
void range_check(const T value, const T min, const T max)

References range_check().

Referenced by nlohmann::json_schema::default_string_format_check(), and rfc3339_date_time_check().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rfc3339_date_time_check()

void anonymous_namespace{string-format-check.cpp}::rfc3339_date_time_check ( const std::string & value)
See also
https://tools.ietf.org/html/rfc3339#section-5.6
* date-fullyear   = 4DIGIT
* date-month      = 2DIGIT  ; 01-12
* date-mday       = 2DIGIT  ; 01-28, 01-29, 01-30, 01-31 based on
*                          ; month/year
* time-hour       = 2DIGIT  ; 00-23
* time-minute     = 2DIGIT  ; 00-59
* time-second     = 2DIGIT  ; 00-58, 00-59, 00-60 based on leap second
*                          ; rules
* time-secfrac    = "." 1*DIGIT
* time-numoffset  = ("+" / "-") time-hour ":" time-minute
* time-offset     = "Z" / time-numoffset
*
* partial-time    = time-hour ":" time-minute ":" time-second
*                  [time-secfrac]
* full-date       = date-fullyear "-" date-month "-" date-mday
* full-time       = partial-time time-offset
*
* date-time       = full-date "T" full-time
* 

NOTE: Per [ABNF] and ISO8601, the "T" and "Z" characters in this syntax may alternatively be lower case "t" or "z" respectively.

Definition at line 142 of file string-format-check.cpp.

143{
144 const static REGEX_NAMESPACE::regex dateTimeRegex{R"(^([0-9]{4}\-[0-9]{2}\-[0-9]{2})[Tt]([0-9]{2}\:[0-9]{2}\:[0-9]{2}(?:\.[0-9]+)?(?:[Zz]|(?:\+|\-)[0-9]{2}\:[0-9]{2}))$)"};
145
146 REGEX_NAMESPACE::smatch matches;
147 if (!REGEX_NAMESPACE::regex_match(value, matches, dateTimeRegex)) {
148 throw std::invalid_argument(value + " is not a date-time string according to RFC 3339.");
149 }
150
151 rfc3339_date_check(matches[1].str());
152 rfc3339_time_check(matches[2].str());
153}
void rfc3339_time_check(const std::string &value)
void rfc3339_date_check(const std::string &value)

References rfc3339_date_check(), and rfc3339_time_check().

Referenced by nlohmann::json_schema::default_string_format_check().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rfc3339_time_check()

void anonymous_namespace{string-format-check.cpp}::rfc3339_time_check ( const std::string & value)
See also
date_time_check
Todo
Could be made more exact by querying a leap second database and choosing the correct maximum in {58,59,60}. This current solution might match some invalid dates but it won't lead to false negatives. This only works if we know the full date, however
Todo
Could be made more exact by querying a leap second database and choosing the correct maximum in {58,59,60}. This current solution might match some invalid dates but it won't lead to false negatives. This only works if we know the full date, however

Definition at line 67 of file string-format-check.cpp.

68{
69 const static REGEX_NAMESPACE::regex timeRegex{R"(^([0-9]{2})\:([0-9]{2})\:([0-9]{2})(\.[0-9]+)?(?:[Zz]|((?:\+|\-)[0-9]{2})\:([0-9]{2}))$)"};
70
71 REGEX_NAMESPACE::smatch matches;
72 if (!REGEX_NAMESPACE::regex_match(value, matches, timeRegex)) {
73 throw std::invalid_argument(value + " is not a time string according to RFC 3339.");
74 }
75
76 auto hour = std::stoi(matches[1].str());
77 auto minute = std::stoi(matches[2].str());
78 auto second = std::stoi(matches[3].str());
79 // const auto secfrac = std::stof( matches[4].str() );
80
81 range_check(hour, 0, 23);
82 range_check(minute, 0, 59);
83
84 int offsetHour = 0,
85 offsetMinute = 0;
86
87 /* don't check the numerical offset if time zone is specified as 'Z' */
88 if (!matches[5].str().empty()) {
89 offsetHour = std::stoi(matches[5].str());
90 offsetMinute = std::stoi(matches[6].str());
91
92 range_check(offsetHour, -23, 23);
93 range_check(offsetMinute, 0, 59);
94 if (offsetHour < 0)
95 offsetMinute *= -1;
96 }
97
103
104 auto day_minutes = hour * 60 + minute - (offsetHour * 60 + offsetMinute);
105 if (day_minutes < 0)
106 day_minutes += 60 * 24;
107 hour = day_minutes % 24;
108 minute = day_minutes / 24;
109
110 if (hour == 23 && minute == 59)
111 range_check(second, 0, 60); // possible leap-second
112 else
113 range_check(second, 0, 59);
114}

References range_check().

Referenced by nlohmann::json_schema::default_string_format_check(), and rfc3339_date_time_check().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rfc3986_uri_check()

void anonymous_namespace{string-format-check.cpp}::rfc3986_uri_check ( const std::string & value)
See also
* URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
*
*  hier-part     = "//" authority path-abempty
*               / path-absolute
*               / path-rootless
*               / path-empty
*
* URI-reference = URI / relative-ref
*
* absolute-URI  = scheme ":" hier-part [ "?" query ]
*
* relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
*
* relative-part = "//" authority path-abempty
*               / path-absolute
*               / path-noscheme
*               / path-empty
*
* scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
*
* authority     = [ userinfo "@" ] host [ ":" port ]
* userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
* host          = IP-literal / IPv4address / reg-name
* port          = *DIGIT
*
* IP-literal    = "[" ( IPv6address / IPvFuture  ) "]"
*
* IPvFuture     = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
*
* IPv6address   =                            6( h16 ":" ) ls32
*               /                       "::" 5( h16 ":" ) ls32
*               / [               h16 ] "::" 4( h16 ":" ) ls32
*               / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
*               / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
*               / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
*               / [ *4( h16 ":" ) h16 ] "::"              ls32
*               / [ *5( h16 ":" ) h16 ] "::"              h16
*               / [ *6( h16 ":" ) h16 ] "::"
*
* h16           = 1*4HEXDIG
* ls32          = ( h16 ":" h16 ) / IPv4address
* IPv4address   = dec-octet "." dec-octet "." dec-octet "." dec-octet
*    dec-octet     = DIGIT                 ; 0-9
*               / %x31-39 DIGIT         ; 10-99
*               / "1" 2DIGIT            ; 100-199
*               / "2" %x30-34 DIGIT     ; 200-249
*               / "25" %x30-35          ; 250-255
*
* reg-name      = *( unreserved / pct-encoded / sub-delims )
*
* path          = path-abempty    ; begins with "/" or is empty
*               / path-absolute   ; begins with "/" but not "//"
*               / path-noscheme   ; begins with a non-colon segment
*               / path-rootless   ; begins with a segment
*               / path-empty      ; zero characters
*
* path-abempty  = *( "/" segment )
* path-absolute = "/" [ segment-nz *( "/" segment ) ]
* path-noscheme = segment-nz-nc *( "/" segment )
* path-rootless = segment-nz *( "/" segment )
* path-empty    = 0<pchar>
*
* segment       = *pchar
* segment-nz    = 1*pchar
* segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
*               ; non-zero-length segment without any colon ":"
*
* pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
*
* query         = *( pchar / "/" / "?" )
*
* fragment      = *( pchar / "/" / "?" )
*
* pct-encoded   = "%" HEXDIG HEXDIG
*
* unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
* reserved      = gen-delims / sub-delims
* gen-delims    = ":" / "/" / "?" / "#" / "[" / "]" / "@"
* sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
*               / "*" / "+" / "," / ";" / "="
*
* 
See also
adapted from: https://github.com/jhermsmeier/uri.regex/blob/master/uri.regex

Definition at line 294 of file string-format-check.cpp.

295{
296 const static std::string scheme{R"(([A-Za-z][A-Za-z0-9+\-.]*):)"};
297 const static std::string hierPart{
298 R"((?:(\/\/)(?:((?:[A-Za-z0-9\-._~!$&'()*+,;=:]|)"
299 R"(%[0-9A-Fa-f]{2})*)@)?((?:\‍[(?:(?:(?:(?:[0-9A-Fa-f]{1,4}:){6}|)"
300 R"(::(?:[0-9A-Fa-f]{1,4}:){5}|)"
301 R"((?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}|)"
302 R"((?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}|)"
303 R"((?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}|)"
304 R"((?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:|)"
305 R"((?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::)(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|)"
306 R"((?:(?:25[0-5]|2[0-4][0-9]|)"
307 R"([01]?[0-9][0-9]?)\.){3}(?:25[0-5]|)"
308 R"(2[0-4][0-9]|)"
309 R"([01]?[0-9][0-9]?))|)"
310 R"((?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|)"
311 R"((?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::)|)"
312 R"([Vv][0-9A-Fa-f]+\.[A-Za-z0-9\-._~!$&'()*+,;=:]+)\‍]|)"
313 R"((?:(?:25[0-5]|)"
314 R"(2[0-4][0-9]|)"
315 R"([01]?[0-9][0-9]?)\.){3}(?:25[0-5]|)"
316 R"(2[0-4][0-9]|)"
317 R"([01]?[0-9][0-9]?)|)"
318 R"((?:[A-Za-z0-9\-._~!$&'()*+,;=]|)"
319 R"(%[0-9A-Fa-f]{2})*))(?::([0-9]*))?((?:\/(?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|)"
320 R"(%[0-9A-Fa-f]{2})*)*)|)"
321 R"(\/((?:(?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|)"
322 R"(%[0-9A-Fa-f]{2})+(?:\/(?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|)"
323 R"(%[0-9A-Fa-f]{2})*)*)?)|)"
324 R"(((?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|)"
325 R"(%[0-9A-Fa-f]{2})+(?:\/(?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|)"
326 R"(%[0-9A-Fa-f]{2})*)*)|))"};
327
328 const static std::string query{R"((?:\?((?:[A-Za-z0-9\-._~!$&'()*+,;=:@\/?]|%[0-9A-Fa-f]{2})*))?)"};
329 const static std::string fragment{
330 R"((?:\#((?:[A-Za-z0-9\-._~!$&'()*+,;=:@\/?]|%[0-9A-Fa-f]{2})*))?)"};
331 const static std::string uriFormat{scheme + hierPart + query + fragment};
332
333 const static REGEX_NAMESPACE::regex uriRegex{uriFormat};
334
335 if (!REGEX_NAMESPACE::regex_match(value, uriRegex)) {
336 throw std::invalid_argument(value + " is not a URI string according to RFC 3986.");
337 }
338}

Referenced by nlohmann::json_schema::default_string_format_check().

Here is the caller graph for this function:

Variable Documentation

◆ decOctet

const std::string anonymous_namespace{string-format-check.cpp}::decOctet {R"((?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]))"}

Definition at line 155 of file string-format-check.cpp.

155{R"((?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]))"}; // matches numbers 0-255

◆ h16

const std::string anonymous_namespace{string-format-check.cpp}::h16 {R"([0-9A-Fa-f]{1,4})"}

Definition at line 157 of file string-format-check.cpp.

157{R"([0-9A-Fa-f]{1,4})"};

◆ h16Left

const std::string anonymous_namespace{string-format-check.cpp}::h16Left {"(?:" + h16 + ":)"}

Definition at line 158 of file string-format-check.cpp.

158{"(?:" + h16 + ":)"};

◆ host

const std::string anonymous_namespace{string-format-check.cpp}::host
Initial value:

Definition at line 182 of file string-format-check.cpp.

182 {
183 "(?:"
184 R"(\‍[(?:)" +
185 ipv6Address + "|" + ipvFuture + R"()\‍])" +
186 "|" + ipv4Address +
187 "|" + regName +
188 ")"};

◆ hostname

const std::string anonymous_namespace{string-format-check.cpp}::hostname {R"(^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$)"}

Definition at line 193 of file string-format-check.cpp.

193{R"(^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$)"};

Referenced by nlohmann::json_schema::default_string_format_check().

◆ ipv4Address

const std::string anonymous_namespace{string-format-check.cpp}::ipv4Address {"(?:" + decOctet + R"(\.){3})" + decOctet}

Definition at line 156 of file string-format-check.cpp.

156{"(?:" + decOctet + R"(\.){3})" + decOctet};

Referenced by nlohmann::json_schema::default_string_format_check().

◆ ipv6Address

const std::string anonymous_namespace{string-format-check.cpp}::ipv6Address
Initial value:
{
"(?:"
"(?:" +
h16Left + "{6}"
"|::" +
h16Left + "{5}"
"|(?:" +
h16 + ")?::" + h16Left + "{4}"
"|(?:" +
h16Left + "{0,1}" + h16 + ")?::" + h16Left + "{3}"
"|(?:" +
h16Left + "{0,2}" + h16 + ")?::" + h16Left + "{2}"
"|(?:" +
h16Left + "{0,3}" + h16 + ")?::" + h16Left +
"|(?:" + h16Left + "{0,4}" + h16 + ")?::"
")(?:" +
h16Left + h16 + "|" + ipv4Address + ")"
"|(?:" +
h16Left + "{0,5}" + h16 + ")?::" + h16 +
"|(?:" + h16Left + "{0,6}" + h16 + ")?::"
")"}

Definition at line 159 of file string-format-check.cpp.

159 {
160 "(?:"
161 "(?:" +
162 h16Left + "{6}"
163 "|::" +
164 h16Left + "{5}"
165 "|(?:" +
166 h16 + ")?::" + h16Left + "{4}"
167 "|(?:" +
168 h16Left + "{0,1}" + h16 + ")?::" + h16Left + "{3}"
169 "|(?:" +
170 h16Left + "{0,2}" + h16 + ")?::" + h16Left + "{2}"
171 "|(?:" +
172 h16Left + "{0,3}" + h16 + ")?::" + h16Left +
173 "|(?:" + h16Left + "{0,4}" + h16 + ")?::"
174 ")(?:" +
175 h16Left + h16 + "|" + ipv4Address + ")"
176 "|(?:" +
177 h16Left + "{0,5}" + h16 + ")?::" + h16 +
178 "|(?:" + h16Left + "{0,6}" + h16 + ")?::"
179 ")"};

Referenced by nlohmann::json_schema::default_string_format_check().

◆ ipvFuture

const std::string anonymous_namespace{string-format-check.cpp}::ipvFuture {R"([Vv][0-9A-Fa-f]+\.[A-Za-z0-9\-._~!$&'()*+,;=:]+)"}

Definition at line 180 of file string-format-check.cpp.

180{R"([Vv][0-9A-Fa-f]+\.[A-Za-z0-9\-._~!$&'()*+,;=:]+)"};

◆ regName

const std::string anonymous_namespace{string-format-check.cpp}::regName {R"((?:[A-Za-z0-9\-._~!$&'()*+,;=]|%[0-9A-Fa-f]{2})*)"}

Definition at line 181 of file string-format-check.cpp.

181{R"((?:[A-Za-z0-9\-._~!$&'()*+,;=]|%[0-9A-Fa-f]{2})*)"};

◆ uuid

const std::string anonymous_namespace{string-format-check.cpp}::uuid {R"([0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12})"}

Definition at line 190 of file string-format-check.cpp.

190{R"([0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12})"};

Referenced by nlohmann::json_schema::default_string_format_check().