16 #ifndef INCLUDE_NN_NLIB_URI_H_ 17 #define INCLUDE_NN_NLIB_URI_H_ 23 #include "nn/nlib/Swap.h" 29 class MemoryOutputStream;
31 template<
size_t N = 1024>
42 return std::make_pair(&buf_[0], cur_);
92 static errno_t DecodeUriComponent(
size_t* written,
char* buf,
size_t n,
const char* first,
97 return DecodeUriComponent(written, buf, N, s);
101 return DecodeUriComponent(written, buf, n, s, s +
nlib_strlen(s));
106 return DecodeUriComponent(written, buf, N, first, last);
108 static std::pair<errno_t, size_t>
111 errno_t e = DecodeUriComponent(&written, buf, n, first, last);
112 return std::make_pair(e, written);
115 static std::pair<errno_t, size_t>
117 return DecodeUriComponent(buf, N, first, last);
119 static std::pair<errno_t, size_t>
121 return DecodeUriComponent(buf, n, s, s +
nlib_strlen(s));
124 static std::pair<errno_t, size_t>
126 return DecodeUriComponent(buf, N, s, s +
nlib_strlen(s));
131 return DecodePath(written, buf, N, s);
135 errno_t e = DecodePath(&written, buf, n, s);
136 return std::make_pair(e, written);
140 return DecodePath(buf, N, s);
143 static errno_t EncodeUriComponent(
size_t* written,
char* buf,
size_t n,
const char* first,
148 return EncodeUriComponent(written, buf, N, first, last, fragment_mode);
152 return EncodeUriComponent(written, buf, n, s, s +
nlib_strlen(s), fragment_mode);
157 return EncodeUriComponent(written, buf, N, s, fragment_mode);
159 static std::pair<errno_t, size_t>
163 errno_t e = EncodeUriComponent(&written, buf, n, first, last, fragment_mode);
164 return std::make_pair(e, written);
167 static std::pair<errno_t, size_t>
170 return EncodeUriComponent(buf, N, first, last, fragment_mode);
172 static std::pair<errno_t, size_t>
174 return EncodeUriComponent(buf, n, s, s +
nlib_strlen(s), fragment_mode);
177 static std::pair<errno_t, size_t>
179 return EncodeUriComponent(buf, N, s, s +
nlib_strlen(s), fragment_mode);
185 return EncodePath(written, buf, N, s);
189 errno_t e = EncodePath(&written, buf, n, s);
190 return std::make_pair(e, written);
194 return EncodePath(buf, N, s);
200 NLIB_DEFMOVE_PIMPL(Uri);
201 bool Parse(
const char* first,
const char* last)
NLIB_NOEXCEPT;
212 bool SetUri(
const char* scheme,
const char* userinfo,
const char* host,
const char* port,
213 const char* path,
const char* query,
const char* fragment)
NLIB_NOEXCEPT;
215 bool ComposeString(
char* buf,
size_t size)
const NLIB_NOEXCEPT;
218 return this->ComposeString(buf, N);
241 bool SetScheme(const
char* first, const
char* last)
NLIB_NOEXCEPT;
242 bool SetUserInfo(const
char* first, const
char* last)
NLIB_NOEXCEPT;
243 bool SetHost(const
char* first, const
char* last)
NLIB_NOEXCEPT;
244 bool SetPort(const
char* first, const
char* last)
NLIB_NOEXCEPT;
245 bool SetPath(const
char* first, const
char* last)
NLIB_NOEXCEPT;
246 bool SetQuery(const
char* first, const
char* last)
NLIB_NOEXCEPT;
247 bool SetFragment(const
char* first, const
char* last)
NLIB_NOEXCEPT;
249 return scheme ? SetScheme(scheme, scheme +
nlib_strlen(scheme))
250 : SetScheme(
nullptr,
nullptr);
253 return userinfo ? SetUserInfo(userinfo, userinfo +
nlib_strlen(userinfo))
254 : SetUserInfo(
nullptr,
nullptr);
257 return host ? SetHost(host, host +
nlib_strlen(host)) : SetHost(
nullptr,
nullptr);
260 return port ? SetPort(port, port +
nlib_strlen(port)) : SetPort(
nullptr,
nullptr);
266 return SetPort(&buf[0], &buf[0] + cnt);
269 return path ? SetPath(path, path +
nlib_strlen(path)) : SetPath(
nullptr,
nullptr);
272 return query ? SetQuery(query, query +
nlib_strlen(query)) : SetQuery(
nullptr,
nullptr);
275 return fragment ? SetFragment(fragment, fragment +
nlib_strlen(fragment))
276 : SetFragment(
nullptr,
nullptr);
280 std::pair<const char*, const char*> x = encoder.GetData();
281 return SetQueryByQueryEncoder_(x.first, x.second);
300 bool SetQueryByQueryEncoder_(const
char* first, const
char* last)
NLIB_NOEXCEPT;
308 NLIB_EQUAL_OPERATOR(
Uri)
310 NLIB_COMPARE_OPERATOR(
Uri)
317 if (p == &buf_[N - 1])
return ERANGE;
323 e = Uri::EncodeUriComponent(&written, p, &buf_[N] - p, key,
false);
324 if (e != 0)
return e;
327 if (p == &buf_[N - 1])
return ERANGE;
330 e = Uri::EncodeUriComponent(&written, p, &buf_[N] - p, value,
false);
331 if (e != 0)
return e;
338 template<
size_t K = 64,
size_t V = 192>
346 buf_key_valid_(false),
347 buf_value_valid_(false) {
349 buf_value_[0] =
'\0';
362 return std::make_pair(e, static_cast<const char*>(
nullptr));
365 std::pair<errno_t, const char*> x = GetKey();
366 if (x.first != 0)
return x.first;
367 if (strcmp(key, x.second) == 0)
return 0;
372 const
char* ptr_beg_;
373 const
char* ptr_end_;
374 const
char* ptr_key_;
376 const
char* ptr_and_;
378 bool buf_value_valid_;
383 template<
size_t K,
size_t V>
385 if (!uri)
return EINVAL;
386 const char* p = uri.GetQuery();
388 ptr_beg_ = ptr_key_ = p;
391 ptr_beg_ = ptr_end_ = &buf_key_[0];
393 ptr_eq_ = ptr_and_ =
nullptr;
394 buf_key_valid_ = buf_value_valid_ =
false;
398 template<
size_t K,
size_t V>
400 ptr_beg_ = ptr_end_ = ptr_key_ = ptr_eq_ = ptr_and_ =
nullptr;
401 buf_key_valid_ = buf_value_valid_ =
false;
404 template<
size_t K,
size_t V>
406 if (ptr_key_ == ptr_end_)
return false;
408 ptr_eq_ = ptr_and_ =
nullptr;
409 buf_key_valid_ = buf_value_valid_ =
false;
412 }
while (ptr_key_ != ptr_end_ && *ptr_key_ ==
'&');
413 return ptr_key_ != ptr_end_;
416 template<
size_t K,
size_t V>
418 if (!HasNext())
return ENOENT;
420 ptr_key_ = (ptr_and_ != ptr_end_) ? ptr_and_ + 1 : ptr_end_;
422 const void* p =
nlib_memchr(ptr_key_,
'&', std::distance(ptr_key_, ptr_end_));
423 ptr_key_ = (p !=
nullptr) ? static_cast<const char*>(p) + 1 : ptr_end_;
425 ptr_eq_ = ptr_and_ =
nullptr;
426 buf_key_valid_ = buf_value_valid_ =
false;
430 template<
size_t K,
size_t V>
432 if (buf_key_valid_)
return std::make_pair(0, &buf_key_[0]);
433 if (!ptr_key_)
return Error(EBADF);
434 if (!HasNext())
return Error(ENOENT);
435 if (!ptr_eq_) SpotKeyValue();
437 errno_t e = Uri::DecodeUriComponent(&w, buf_key_, K, ptr_key_, ptr_eq_);
438 if (e != 0)
return Error(e);
439 buf_key_valid_ =
true;
440 return std::make_pair(0, &buf_key_[0]);
443 template<
size_t K,
size_t V>
445 if (buf_value_valid_)
return std::make_pair(0, &buf_value_[0]);
446 if (!ptr_key_)
return Error(EBADF);
447 if (!HasNext())
return Error(ENOENT);
448 if (!ptr_eq_) SpotKeyValue();
449 if (ptr_eq_ != ptr_and_) {
451 errno_t e = Uri::DecodeUriComponent(&w, buf_value_, V, ptr_eq_ + 1, ptr_and_);
452 if (e != 0)
return Error(e);
454 buf_value_[0] =
'\0';
456 buf_value_valid_ =
true;
457 return std::make_pair(0, &buf_value_[0]);
460 template<
size_t K,
size_t V>
461 std::pair<errno_t, const char*>
465 e = GetKeyWithCompare_(key);
466 if (e == 0)
return std::make_pair(0, &buf_key_[0]);
467 if (e != ESRCH)
return Error(e);
468 }
while (MoveNext() == 0);
472 template<
size_t K,
size_t V>
475 ptr_eq_ = ptr_and_ =
nullptr;
476 buf_key_valid_ = buf_value_valid_ =
false;
479 template<
size_t K,
size_t V>
481 const void* p_and =
nlib_memchr(ptr_key_,
'&', std::distance(ptr_key_, ptr_end_));
482 ptr_and_ = p_and ?
static_cast<const char*
>(p_and) : ptr_end_;
483 const void* p_eq =
nlib_memchr(ptr_key_,
'=', std::distance(ptr_key_, ptr_and_));
484 ptr_eq_ = p_eq ?
static_cast<const char*
>(p_eq) : ptr_and_;
488 #ifndef __cpp_rvalue_references 491 #endif // INCLUDE_NN_NLIB_URI_H_ static std::pair< errno_t, size_t > DecodeUriComponent(char(&buf)[N], const char *first, const char *last) noexcept
A template overload of the above function.
static errno_t DecodeUriComponent(size_t *written, char *buf, size_t n, const char *s) noexcept
A parameter omitted version of the above function which receives a null terminated string...
bool SetQuery(const char *query) noexcept
Sets the query string, excluding the "?" character at its beginning.
bool SetPath(const char *path) noexcept
Sets the path.
static errno_t EncodeUriComponent(size_t *written, char *buf, size_t n, const char *s, bool fragment_mode) noexcept
static std::pair< errno_t, size_t > DecodeUriComponent(char *buf, size_t n, const char *s) noexcept
A parameter omitted version of the above function which receives a null terminated string...
static errno_t DecodePath(size_t *written, char(&buf)[N], const char *s) noexcept
A template overload of the above function.
static errno_t DecodeUriComponent(size_t *written, char(&buf)[N], const char *s) noexcept
A template overload of the above function.
static std::pair< errno_t, size_t > DecodeUriComponent(char(&buf)[N], const char *s) noexcept
A template overload of the above function.
static std::pair< errno_t, size_t > DecodePath(char(&buf)[N], const char *s) noexcept
A parameter omitted version of the above function which passes settings as the default value...
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
#define NLIB_SAFE_BOOL(class_name, exp)
Defines a safe operator bool function in the class. Uses the C++11 explicit bool if it is available f...
static bool IsIpv4(const nlib_utf8_t *str) noexcept
A parameter omitted version of the above function which receives a null terminated string...
static std::pair< errno_t, size_t > EncodePath(char *buf, size_t n, const char *s) noexcept
test
bool SetFragment(const char *fragment) noexcept
Sets the fragment string, excluding the "#" character at its beginning.
#define NLIB_CEXPR14
constexpr is defined if C++14 constexpr is available for use. If not, holds an empty string...
static errno_t EncodePath(size_t *written, char(&buf)[N], const char *s) noexcept
A template overload of the above function.
constexpr Uri() noexcept
Instantiates the object with default parameters (default constructor).
static errno_t DecodeUriComponent(size_t *written, char(&buf)[N], const char *first, const char *last) noexcept
A template overload of the above function.
constexpr UriQueryDecoder() noexcept
Instantiates the object with default parameters (default constructor). Requires initialization with I...
The object has not been initialized.
Defines the class that resembles std::vector but can store objects that cannot be copied...
bool IsAbsolute() const noexcept
Returns true if the URI is an absolute URI. This function determines the string is an absolute URI if...
bool SetPortNumber(int port) noexcept
Sets the port number.
static std::pair< errno_t, size_t > EncodeUriComponent(char *buf, size_t n, const char *s, bool fragment_mode)
An absolute URI needs to be specified.
Failed to allocate memory.
static std::pair< errno_t, size_t > EncodeUriComponent(char *buf, size_t n, const char *first, const char *last, bool fragment_mode) noexcept
Percent-encodes a string. Returns a pair of the error value and the number of bytes in the encoded st...
bool SetHost(const char *host) noexcept
Sets the hostname.
static errno_t EncodeUriComponent(size_t *written, char(&buf)[N], const char *first, const char *last, bool fragment_mode) noexcept
A template overload of the above function.
static bool IsEmailAddress(const nlib_utf8_t *str) noexcept
A parameter omitted version of the above function which receives a null terminated string...
const char * c_str() const noexcept
Returns the encoded query string.
static errno_t EncodeUriComponent(size_t *written, char(&buf)[N], const char *s, bool fragment_mode) noexcept
A template overload of the above function.
bool ComposeString(char(&buf)[N]) const noexcept
A template overload of the above function.
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
#define NLIB_CEXPR
Defines constexpr if it is available for use. If not, holds an empty string.
A file that contains the configuration information for each development environment.
Failed to normalize the (absolute) path.
static std::pair< errno_t, size_t > EncodeUriComponent(char(&buf)[N], const char *s, bool fragment_mode)
A template overload of the above function.
bool SetPort(const char *port) noexcept
Sets the port number as a string, excluding the colon.
static bool IsUriReference(const nlib_utf8_t *str) noexcept
A parameter omitted version of the above function which receives a null terminated string...
The class for parsing and constructing regular URIs.
static bool IsHostName(const nlib_utf8_t *str) noexcept
A parameter omitted version of the above function which receives a null terminated string...
static bool IsIpv6(const nlib_utf8_t *str) noexcept
A parameter omitted version of the above function which receives a null terminated string...
bool Parse(const char *str) noexcept
A parameter omitted version of the above function which receives a null terminated string...
The class template to parse URI queries.
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
static std::pair< errno_t, size_t > EncodeUriComponent(char(&buf)[N], const char *first, const char *last, bool fragment_mode) noexcept
A template overload of the above function.
static std::pair< errno_t, size_t > DecodePath(char *buf, size_t n, const char *s) noexcept
Decodes a percent-encoded string. This function is the same as DecodeUriComponent, except that it returns EILSEQ if the decoded character is the forward slash ('/').
bool SetQuery(const UriQueryEncoder< N > &encoder) noexcept
Sets the query string, excluding the "?" character at its beginning.
UriQueryEncoder() noexcept
Instantiates the object with default parameters (default constructor).
std::pair< const char *, const char * > GetData() const noexcept
Returns the beginning and end of the encoded query string.
The class for creating URI queries.
static std::pair< errno_t, size_t > EncodePath(char(&buf)[N], const char *s) noexcept
A template overload of the above function.
static bool IsUri(const nlib_utf8_t *str) noexcept
A parameter omitted version of the above function which receives a null terminated string...
static std::pair< errno_t, size_t > DecodeUriComponent(char *buf, size_t n, const char *first, const char *last) noexcept
Decodes a percent-encoded string. Returns a pair of the error value and the number of bytes in the de...
bool SetUserInfo(const char *userinfo) noexcept
Sets user-specific information, including the user name and password, associated with the specified U...
Error
An error value, as an enumerator, that can be obtained with GetError().