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
上記関数のテンプレートオーバーロードです。
static errno_t DecodeUriComponent(size_t *written, char *buf, size_t n, const char *s) noexcept
上記関数の引数省略版で、ヌル終端する文字列を受け取ります。
bool SetQuery(const char *query) noexcept
クエリ文字列(先頭の?は含まない)を設定します。
bool SetPath(const char *path) noexcept
パスを設定します。
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
上記関数の引数省略版で、ヌル終端する文字列を受け取ります。
static errno_t DecodePath(size_t *written, char(&buf)[N], const char *s) noexcept
上記関数のテンプレートオーバーロードです。
static errno_t DecodeUriComponent(size_t *written, char(&buf)[N], const char *s) noexcept
上記関数のテンプレートオーバーロードです。
static std::pair< errno_t, size_t > DecodeUriComponent(char(&buf)[N], const char *s) noexcept
上記関数のテンプレートオーバーロードです。
static std::pair< errno_t, size_t > DecodePath(char(&buf)[N], const char *s) noexcept
上記関数の引数省略版で、settingsをデフォルト値で渡します。
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
TypeName で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
#define NLIB_SAFE_BOOL(class_name, exp)
クラス内に安全なoperator bool()を定義します。 可能であればC++11のexplicit boolを利用します。 ...
static bool IsIpv4(const nlib_utf8_t *str) noexcept
上記関数の引数省略版で、ヌル終端する文字列を受け取ります。
static std::pair< errno_t, size_t > EncodePath(char *buf, size_t n, const char *s) noexcept
test
bool SetFragment(const char *fragment) noexcept
フラグメント文字列(先頭の::は含まない)を設定します。
#define NLIB_CEXPR14
C++14のconstexprが利用可能であればconstexprが定義されます。そうでない場合は空文字列です。 ...
static errno_t EncodePath(size_t *written, char(&buf)[N], const char *s) noexcept
上記関数のテンプレートオーバーロードです。
constexpr Uri() noexcept
デフォルトコンストラクタです。
static errno_t DecodeUriComponent(size_t *written, char(&buf)[N], const char *first, const char *last) noexcept
上記関数のテンプレートオーバーロードです。
constexpr UriQueryDecoder() noexcept
デフォルトコンストラクタです。実行後Init()による初期化を必要とします。
std::vectorに似ていますが、コピーできないオブジェクトを格納可能なクラスが定義されています。 ...
bool IsAbsolute() const noexcept
URIが絶対URIであればtrueを返します。この関数ではschemeが指定されていれば絶対URIであると判断しています...
bool SetPortNumber(int port) noexcept
ポート番号を設定します。
static std::pair< errno_t, size_t > EncodeUriComponent(char *buf, size_t n, const char *s, bool fragment_mode)
static std::pair< errno_t, size_t > EncodeUriComponent(char *buf, size_t n, const char *first, const char *last, bool fragment_mode) noexcept
文字列を%エンコードします。エラー値とエンコードされた文字列のバイト数(ヌル文字を含まず)のペアを返しま...
bool SetHost(const char *host) noexcept
ホスト名を設定します。
static errno_t EncodeUriComponent(size_t *written, char(&buf)[N], const char *first, const char *last, bool fragment_mode) noexcept
上記関数のテンプレートオーバーロードです。
static bool IsEmailAddress(const nlib_utf8_t *str) noexcept
上記関数の引数省略版で、ヌル終端する文字列を受け取ります。
const char * c_str() const noexcept
エンコードされたクエリ文字列を返します。
static errno_t EncodeUriComponent(size_t *written, char(&buf)[N], const char *s, bool fragment_mode) noexcept
上記関数のテンプレートオーバーロードです。
bool ComposeString(char(&buf)[N]) const noexcept
上記関数のテンプレートオーバーロードです。
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
#define NLIB_CEXPR
利用可能であればconstexprが定義されます。そうでない場合は空文字列です。
static std::pair< errno_t, size_t > EncodeUriComponent(char(&buf)[N], const char *s, bool fragment_mode)
上記関数のテンプレートオーバーロードです。
bool SetPort(const char *port) noexcept
ポート番号の文字列(:は含まない)を設定します。
static bool IsUriReference(const nlib_utf8_t *str) noexcept
上記関数の引数省略版で、ヌル終端する文字列を受け取ります。
一般的なURIをパースしたり構築したりするためのクラスです。
static bool IsHostName(const nlib_utf8_t *str) noexcept
上記関数の引数省略版で、ヌル終端する文字列を受け取ります。
static bool IsIpv6(const nlib_utf8_t *str) noexcept
上記関数の引数省略版で、ヌル終端する文字列を受け取ります。
bool Parse(const char *str) noexcept
上記関数の引数省略版で、ヌル終端する文字列を受け取ります。
URIのクエリをパースするためのクラステンプレートです。
#define NLIB_FINAL
利用可能であればfinalが定義されます。そうでない場合は空文字列です。
static std::pair< errno_t, size_t > EncodeUriComponent(char(&buf)[N], const char *first, const char *last, bool fragment_mode) noexcept
上記関数のテンプレートオーバーロードです。
static std::pair< errno_t, size_t > DecodePath(char *buf, size_t n, const char *s) noexcept
%エンコードされた文字列をデコードします。 デコードされた文字が'/'の場合にEILSEQを返すこと以外は、Deco...
bool SetQuery(const UriQueryEncoder< N > &encoder) noexcept
クエリ文字列(先頭の?は含まない)を設定します。
UriQueryEncoder() noexcept
デフォルトコンストラクタです。
std::pair< const char *, const char * > GetData() const noexcept
エンコードされたクエリ文字列の先頭と末尾を返します。
static std::pair< errno_t, size_t > EncodePath(char(&buf)[N], const char *s) noexcept
上記関数のテンプレートオーバーロードです。
static bool IsUri(const nlib_utf8_t *str) noexcept
上記関数の引数省略版で、ヌル終端する文字列を受け取ります。
static std::pair< errno_t, size_t > DecodeUriComponent(char *buf, size_t n, const char *first, const char *last) noexcept
%エンコードされた文字列をデコードします。エラー値とデコードされた文字列のバイト数(ヌル文字を含まず)の...
bool SetUserInfo(const char *userinfo) noexcept
指定した URI に関連付けられているユーザー名、パスワードなどのユーザー固有の情報を設定します。 ...
Error
GetError()で取得することのできるエラー値の列挙型です。